package com.yc.tomcat.impl;

import com.yc.tomcat.Cookie;
import com.yc.tomcat.HttpServletRequest;
import com.yc.tomcat.HttpServletResponse;
import com.yc.tomcat.HttpSession;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpServletResponseImpl implements HttpServletResponse {
    private Socket socket;
    private HttpServletRequest request;
    private int status=200;
    private String msg="OK";
    private Map<String,String> headerMap=new HashMap<>();
    //单独存放cookie
    private List<Cookie> cookieList=new ArrayList<>();

    public HttpServletResponseImpl(Socket socket, HttpServletRequest request){
        this.socket=socket;
        this.request=request;
    }

    //我们通过Servlet输出的文字信息用StringWriter流保存数据 使用StringWriter流保存Servlet输出的文字信息可以方便地保存数据，提高性能，增加灵活性和可定制性。
    //字符串输出流 =》 资源流
    StringWriter sw=new StringWriter(); // StringWriter看作是一个将数据写入到内存中的字符串缓存，可以通过调用toString()方法获取缓存中的字符串内容。        sw作为一个缓存区 可以在写入数据时进行一些处理操作，比如格式化、加密等。这样可以对输出的文字信息进行一些处理，增加灵活性和可定制性。
    // 打印输出流 =》 处理流
    PrintWriter pw=new PrintWriter(sw);// PrintWriter是Java中用于写入字符数据的类，它可以将数据写入到不同类型的输出流中

    @Override
    public PrintWriter getWriter() {

        return pw;
    }

    @Override
    public OutputStream getOutputStream() {
        try {
            return socket.getOutputStream();
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
    }

    @Override
    public void setContentType(String type) {
     setHeader("Content-Type",type);
    }

    @Override
    public void setStatus(int status, String msg) {
        this.status=status;
        this.msg=msg;
    }

    @Override
    public void setHeader(String name, String value) {
        headerMap.put(name,value);
    }

    @Override
    public void flushBuffer() {
        try {
            OutputStream out=socket.getOutputStream();
            //头行
            out.write(String.format("%s %d %s\n",request.getProtocol(),status,msg).getBytes());

            //头部参数
            for(Map.Entry<String,String> entry:headerMap.entrySet()){
                String name = entry.getKey();
                String value = entry.getValue();
                out.write(String.format("%s: %s\n",name,value).getBytes());
            }

            //保存会话ID到cookie中
            HttpSession session=request.getSession();
            String sessionId=session.getId();
            Cookie sessionCookie=new CookieImpl("JSESSIONID",sessionId);
            cookieList.add(sessionCookie);


            //cookie
            for (Cookie cookie : cookieList) {
                out.write(("Set-Cookie:"+cookie.toString()).getBytes()); //遍历设置cookie
            /*    Set-Cookie :c=500; Max-Age=6000
                Set-Cookie :JSESSIONID=cdec6f36-05f5-43f8-970f-0e5679506bde*/
            }

            //空行
            out.write("\n".getBytes());
            //body内容
            out.write(sw.getBuffer().toString().getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void sendRedirect(String location) {

        //  响应结果码：301
        setStatus(301,"Redirect");
        //响应头参数:Location
        setHeader("Location",location);

    }

    @Override
    public void addCookie(Cookie cookie) {
            cookieList.add(cookie);
    }
}
